package org.rency.ues.engine.service.impl;

import org.rency.common.utils.security.Base64Utils;
import org.rency.common.utils.security.RSAUtils;
import org.rency.ues.common.UesDict;
import org.rency.ues.domain.request.SignRequest;
import org.rency.ues.domain.request.VerifySignRequest;
import org.rency.ues.domain.response.SignResponse;
import org.rency.ues.domain.response.VerifySignResponse;
import org.rency.ues.domain.support.Certification;
import org.rency.ues.domain.support.UesResult;
import org.rency.ues.engine.service.CertificationService;
import org.rency.ues.engine.service.UesService;
import org.rency.ues.engine.service.VerifyService;
import org.rency.ues.engine.validator.RequestValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 加签/验签服务实现
 *
 * @author: Created by user_rcy@163.com on 2016/08/31.
 * @version: V1.0.0
 * @since JDK 1.8
 */
public class VerifyServiceImpl implements VerifyService {

    private static final Logger logger = LoggerFactory.getLogger(VerifyServiceImpl.class);

    private RequestValidator<SignRequest, SignResponse> signValidator;

    private RequestValidator<VerifySignRequest, VerifySignResponse> verifySignValidator;

    private CertificationService certificationService;

    private UesService uesService;

    @Override
    public SignResponse sign(SignRequest request) {
        logger.info("加签请求,{}.",request);
        long start = System.currentTimeMillis();
        SignResponse response = signValidator.validator(request);
        if(!response.isSuccess()){
            return response;
        }
        try{
            Certification certification = certificationService.getCertification(request.getSerialNo());
            if(certification == null){
                logger.warn("未获取到证书,{}.",request.getSerialNo());
                return SignResponse.fail(UesDict.CHINESE_EMPTY_CERT_MSG);
            }
            UesResult uesResult = uesService.getPlainData(request.getEncryptType(),request.getEncryptedKey(),request.getEncryptedData(),certification);
            if(!uesResult.isSuccess()){
                logger.error("解析密文失败,{}.",uesResult);
                return SignResponse.fail(uesResult.getReturnMessage());
            }
            String orgiData = uesResult.getData();
            byte[] signDataByte = null;
            switch (request.getEncryptType()){
                case RSA:
                    signDataByte = RSAUtils.sign(Base64Utils.decodeBase64(orgiData),certification.getPrivateKey());
                    break;
                default:
                    logger.error("加签方式不支持:{}.",request.getEncryptType().getCode());
                    return SignResponse.fail(UesDict.CHINESE_FAIL_MSG);
            }
            if(signDataByte == null){
                logger.error("对原文做加签失败.");
                return SignResponse.fail(UesDict.CHINESE_FAIL_MSG);
            }
            String signData = Base64Utils.encodeBase64(signDataByte);
            response.setSignData(signData);
            logger.info("加签完成,{}.",response);
        }catch (Exception e){
            logger.error("加签请求未知异常,原始请求:{}.",request,e);
            return SignResponse.fail(UesDict.CHINESE_FAIL_MSG);
        }finally {
            logger.info("加签请求完成,耗时{}ms.",System.currentTimeMillis()- start);
        }
        return response;
    }

    @Override
    public VerifySignResponse verifySign(VerifySignRequest request) {
        logger.info("验签请求,{}.",request);
        long start = System.currentTimeMillis();
        VerifySignResponse response = verifySignValidator.validator(request);
        if(!response.isSuccess()){
            return response;
        }
        try{
            Certification certification = certificationService.getCertification(request.getSerialNo());
            if(certification == null){
                logger.warn("未获取到证书,{}.",request.getSerialNo());
                return VerifySignResponse.fail(UesDict.CHINESE_EMPTY_CERT_MSG);
            }
            boolean isVerified = false;
            switch (request.getEncryptType()){
                case RSA:
                    isVerified = RSAUtils.checkSign(Base64Utils.decodeBase64(request.getOrgiData()),Base64Utils.decodeBase64(request.getSignData()),certification.getCertificate().getPublicKey());
                    break;
                default:
                    logger.error("验签方式不支持:{}.",request.getEncryptType().getCode());
                    return VerifySignResponse.fail(UesDict.CHINESE_FAIL_MSG);
            }
            response.setVerified(isVerified);
            logger.info("验签完成,{}.",response);
        }catch (Exception e){
            logger.error("验签请求未知异常,原始请求:{}.",request,e);
            return VerifySignResponse.fail(UesDict.CHINESE_FAIL_MSG);
        }finally {
            logger.info("验签请求完成,耗时{}ms.",System.currentTimeMillis()- start);
        }
        return response;
    }

    public void setSignValidator(RequestValidator<SignRequest, SignResponse> signValidator) {
        this.signValidator = signValidator;
    }

    public void setVerifySignValidator(RequestValidator<VerifySignRequest, VerifySignResponse> verifySignValidator) {
        this.verifySignValidator = verifySignValidator;
    }

    public void setCertificationService(CertificationService certificationService) {
        this.certificationService = certificationService;
    }

    public void setUesService(UesService uesService) {
        this.uesService = uesService;
    }
}
